home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / fp / ifp_unix.lzh / ifp / interp / node.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-23  |  10.0 KB  |  430 lines

  1.  
  2. /****** node.c ********************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                         Version: 0.5                 **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison       Date:   May 2, 1987          **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23. #include <stdio.h>
  24. #include "struct.h"
  25. #include "node.h"
  26. #include "umax.h"
  27. #include "string.h"
  28.  
  29. /********************************* NODE RULES ******************************
  30.  
  31. Function definitions are stored in nodes, which are arranged in a tree
  32. structure mimicking the UNIX file structure.  Below is an example:
  33.  
  34.            Rm
  35.            |
  36.            Am---Bi----Cm-------Dd
  37.            |          |
  38.            Xd         Yd--Zd
  39.  
  40. Rm is the root node, with children Am,Bi,Cm, and Dd. Nodes can be one of three
  41. types: module (m), import (i), or definition (d).  Only definition nodes
  42. have a reference count greater than 1.  Only module nodes have children.
  43.  
  44.  ****************************** end of node rules **************************/
  45.  
  46. /* Free nodes have NREF == 0 and are linked by NodeSib field */
  47. NodePtr FreeNode = NULL;
  48.  
  49.  
  50. NodePtr RootNode,SysNode,LogicNode,ArithNode;
  51.  
  52. /*
  53.  * DelNPtr
  54.  *
  55.  * Note: node pointers always have a parent pointer to them, so
  56.  *       we don't have to delete them here.
  57.  *
  58.  * Input
  59.  *    N = pointer to node
  60.  */
  61. void DelNPtr (N)
  62.    NodePtr N;
  63.    {
  64.       rsemaphore_enter (NRefSemaphore);
  65.       if (N != NULL) N->NRef--;
  66.       rsemaphore_exit (NRefSemaphore);
  67.    }
  68.  
  69.  
  70. /*
  71.  * CopyNPtr
  72.  */
  73. NodePtr CopyNPtr (N)
  74.    NodePtr N;
  75.    {
  76.       rsemaphore_enter (NRefSemaphore);
  77.       if (N != NULL && !++N->NRef) IntError ("CopyNPtr: too many refs");
  78.       rsemaphore_exit (NRefSemaphore);
  79.       return N;
  80.    }
  81.  
  82. /*
  83.  * NewNode
  84.  *
  85.  * Point *N to new node from free list.  The input value of *N is
  86.  * put in the NodeSib field of the new node.
  87.  *
  88.  * A SysError may occur, in which case *N is unchanged.
  89.  */
  90. private void NewNode (N)
  91.    NodePtr *N;
  92.    {
  93.       extern NodePtr AllocNodePage ();
  94.       register NodePtr T;
  95.  
  96.       rsemaphore_enter (NRefSemaphore);
  97.       if (FreeNode == NULL && (FreeNode = AllocNodePage ()) == NULL) {
  98.      printf ("NO MORE NODE CELLS LEFT\n");
  99.      SysError = NO_NODE_FREE;
  100.       } else {
  101.      T = FreeNode;
  102.      FreeNode = FreeNode->NodeSib;
  103.      T->NodeSib = *N;
  104.      *N = T;
  105.       }
  106.       rsemaphore_exit (NRefSemaphore);
  107.    }
  108.  
  109.  
  110. /*
  111.  * FindNode
  112.  *
  113.  * Find a node (within a module for IFP) with a specified name.
  114.  *
  115.  * Input
  116.  *      M = pointer to module node (IFP only) 
  117.  *      S = pointer to string
  118.  *
  119.  * Output
  120.  *      result = NULL if node not found, pointer to node otherwise.
  121.  *         OOFP version always finds a node, thus it never returns NULL.
  122.  */
  123.  
  124. NodePtr FindNode (M,S)
  125.    register NodePtr M;
  126.    StrPtr S;
  127.    {
  128.       if (M->NodeType == MODULE)
  129.      for (M = M->NodeData.NodeMod.FirstChild; M!=NULL; M=M->NodeSib)
  130.         if (0==StrComp (M->NodeName,S)) return M;
  131.       return NULL;
  132.    }
  133.  
  134.  
  135. /*
  136.  * MakePath
  137.  *
  138.  * Make the path list for a given node
  139.  *
  140.  * Input
  141.  *      *N = module node
  142.  * Output
  143.  *      *result = path list
  144.  */
  145. ListPtr MakePath (N)
  146.    NodePtr N;
  147.    {
  148.       ListPtr P;
  149.  
  150.       rsemaphore_enter (NRefSemaphore);
  151.       P=NULL;
  152.       for (; N->NodeParent != NULL; N=N->NodeParent)
  153.       {
  154.      NewList (&P,1L);
  155.      P->Val.Tag = STRING;
  156.      P->Val.String = CopySPtr (N->NodeName);
  157.       }
  158.       rsemaphore_exit (NRefSemaphore);
  159.       return P;
  160.    }
  161.  
  162. /*
  163.  * MakeChild
  164.  *
  165.  * Find (or create if necessary) a new child node with a specified name.
  166.  *
  167.  * Input
  168.  *    M = Parent node
  169.  *    S = name of child
  170.  *
  171.  * Output
  172.  *    N = pointer to child
  173.  *
  174.  * A SysError may occur.
  175.  */
  176. NodePtr MakeChild  (M,S)
  177.    NodePtr M;
  178.    StrPtr S;
  179.    {
  180.       register NodePtr N;
  181.  
  182.       rsemaphore_enter (NRefSemaphore);
  183.       N = FindNode (M,S);
  184.       if (N==NULL) {
  185.      NewNode (&M->NodeData.NodeMod.FirstChild);
  186.      if (SysError) {
  187.         N = NULL;
  188.         goto exit;
  189.      }
  190.      N = M->NodeData.NodeMod.FirstChild;
  191.      N->NodeParent = M;
  192.      N->NodeName = CopySPtr (S);
  193.      N->NodeType = NEWNODE;
  194.       }
  195. exit:
  196.       rsemaphore_exit (NRefSemaphore);
  197.       return N;
  198.    }
  199.  
  200. /*
  201.  * Initialize a module node
  202.  *
  203.  * Input
  204.  *      M = pointer to new node
  205.  */
  206. void InitModule (M)
  207.    register NodePtr M;
  208.    {
  209.       M->NodeType = MODULE;
  210.       M->NodeData.NodeMod.FirstChild = NULL;
  211.       ReadImport (M);
  212.    }
  213.  
  214. /*
  215.  * MakeNode 
  216.  *
  217.  * Create all nodes required by a path.
  218.  *
  219.  * Input
  220.  *      Path = pointer to path list (singleton for OOFP)
  221.  *      Type = type to make node if new node (IFP only)
  222.  *
  223.  * Output
  224.  *      result = pointer to node specified by path or
  225.  *               NULL if an error occurred.
  226.  */
  227. NodePtr MakeNode (Path,Type)
  228.    int Type;
  229.    ListPtr Path;
  230.    {
  231.       register NodePtr M;
  232.  
  233.       rsemaphore_enter (NRefSemaphore); {
  234.          register ListPtr P;
  235.          M = RootNode;
  236.          for (P=Path; P != NULL; P=P->Next)
  237.         if (P->Val.Tag != STRING) return NULL;
  238.         else {
  239.            M = MakeChild (M,P->Val.String);
  240.            if (M->NodeType == NEWNODE)
  241.               if (P->Next!=NULL) InitModule (M);
  242.               else
  243.              switch (M->NodeType = Type) {
  244.                 case DEF:
  245.                   M->NodeData.NodeDef.DefCode.Tag = BOTTOM;
  246.                M->NodeData.NodeDef.DefFlags = 0;
  247.                break;
  248.                 case MODULE:
  249.                InitModule (M);
  250.                break;
  251.              }
  252.         }
  253.       } rsemaphore_exit (NRefSemaphore);
  254.       return M;
  255.    }
  256.  
  257. /*
  258.  * DelImport
  259.  *
  260.  * Delete all information affected by the %IMPORT file for a module node
  261.  * in preparation for rereading the %IMPORT file.
  262.  *
  263.  * Input
  264.  *      M = pointer to module node
  265.  *
  266.  * Notes
  267.  *      IMPORT nodes can be returned to the free list since their
  268.  *      reference counts are always 1.
  269.  */
  270. void DelImport (M)
  271.    NodePtr M;
  272.    {
  273.       register NodePtr *L;
  274.       register NodePtr N;
  275.  
  276.       rsemaphore_enter (NRefSemaphore);
  277.       for (L = &M->NodeData.NodeMod.FirstChild; (N = *L)!= NULL; )
  278.  
  279.      switch (N->NodeType) {
  280.     
  281.         case IMPORT:        /* Return IMPORT nodes to free list */
  282.            DelSPtr (N->NodeName);
  283.            RepTag (&N->NodeData.NodeImp.ImpDef,BOTTOM);
  284.            Rot3 ((MetaPtr) &FreeNode, (MetaPtr) L, (MetaPtr) &N->NodeSib);
  285.            break;
  286.  
  287.         case DEF:           /* Delete local function definitions */
  288.            if (N->NodeData.NodeDef.DefCode.Tag != CODE) 
  289.           RepTag (&N->NodeData.NodeDef.DefCode,BOTTOM);
  290.            L = &N->NodeSib;
  291.            break;
  292.  
  293.         case MODULE:
  294.            L = &N->NodeSib;
  295.            break;
  296.  
  297.         default:
  298.            printf ("Invalid NodeType in node tree: %d\n",N->NodeType);
  299.            L = &N->NodeSib;
  300.            break;
  301.      }
  302.       rsemaphore_exit (NRefSemaphore);
  303.    }
  304.  
  305. /*
  306.  * LinkPath
  307.  *
  308.  * Convert a path list to a definition node if possible.
  309.  *
  310.  * Input
  311.  *      *Def = path list
  312.  *
  313.  * Output
  314.  *      *Def = node or not changed if error occurs
  315.  */
  316. void LinkPath (Path)
  317.    ObjectPtr Path;
  318.    {
  319.       register NodePtr N;
  320.  
  321.       rsemaphore_enter (NRefSemaphore);
  322.       N = MakeNode (Path->List,DEF);
  323.       if (N != NULL) {
  324.      RepTag (Path,NODE);
  325.      Path->Node = CopyNPtr (N);
  326.       }
  327.       rsemaphore_exit (NRefSemaphore);
  328.    }
  329.  
  330. /*
  331.  * SignExtend
  332.  *
  333.  * Sign extend a byte.  Not all machines have signed characters.
  334.  */    
  335. #define SignExtend(B) ((((B) + 0x80) & 0xFF) - 0x80)
  336.  
  337. /*
  338.  * PrimDef
  339.  *
  340.  * Define a primitive function
  341.  *
  342.  * Input
  343.  *      *F = object code for function
  344.  *      S = name of function
  345.  *      M = module in which to put function 
  346.  *      K = code parameter value
  347.  *
  348.  * Output
  349.  *      result = pointer to node containing function
  350.  */
  351. /* VARARGS3 */
  352. NodePtr PrimDef (F,S,M,K)
  353.    NodePtr M;
  354.    int (*F) ();
  355.    char *S;        
  356.    char K;
  357.    {
  358.       register NodePtr N;
  359.       StrPtr T = MakeString (S);
  360.       DefPtr D;
  361.  
  362.       N = MakeChild (M,T);
  363.       D = &N->NodeData.NodeDef;
  364.       N->NodeType = DEF;
  365.       D->DefCode.Tag = CODE;
  366.       D->DefFlags = 0;
  367.       D->DefCode.Code.CodePtr = F;
  368.       D->DefCode.Code.CodeParam = SignExtend (K);
  369.       DelSPtr (T);
  370.       return N;
  371.    }
  372.  
  373.  
  374. /*
  375.  * GroupDef
  376.  *
  377.  * Define a group of functions.
  378.  *
  379.  * Input
  380.  *     T = pointer to table of functions
  381.  *     N = number entries in table
  382.  *     M = module node (IFP only)
  383.  */
  384. void GroupDef (T,N,M)
  385.    NodePtr M;
  386.    register OpDef *T;
  387.    int N;
  388.    {
  389.       while (--N >= 0) {
  390.      (void) PrimDef (T->OpPtr,
  391.              T->OpName,
  392.                   M,
  393.                  T->OpParam);
  394.      T++;
  395.       }
  396.    }
  397.  
  398.  
  399. /*
  400.  * InitNode (IFP only)
  401.  *
  402.  * Initialize root node and 'sys' subnode.
  403.  */
  404. void InitNode ()
  405.    {
  406.       register NodePtr R;
  407.  
  408.       if (Debug & DebugInit) printf ("enter InitNode\n");
  409.       RootNode = NULL;
  410.       NewNode (&RootNode);
  411.       R = RootNode;
  412.       R->NodeSib = NULL;
  413.       R->NodeParent = NULL;
  414.       R->NodeType = MODULE;
  415.       R->NodeName = MakeString ("ROOT");
  416.       R->NodeData.NodeMod.FirstChild = NULL;
  417.       SysNode = MakeChild (R,MakeString ("sys"));
  418.       InitModule (SysNode);
  419.       R = MakeChild (R,MakeString ("math"));
  420.       InitModule (R);
  421.       ArithNode = MakeChild (R,MakeString ("arith"));
  422.       InitModule (ArithNode);
  423.       LogicNode = MakeChild (R,MakeString ("logic"));
  424.       InitModule (LogicNode);
  425.       if (Debug & DebugInit) printf ("exit InitNode\n");
  426.    }
  427.  
  428.  
  429. /****************************** end of node.c ******************************/
  430.